﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Serialization;
using System.Runtime.InteropServices;
using Microsoft.Office.Interop.Excel;
using MVVM.Core;

namespace ObjectModel.Excel
{
    /// <summary>
    /// Holds serializable information about a range object's parent workbook and worksheet.
    /// </summary>
    public class  OfflineRangeOld : NotificationBase, IOfflineRange
    {
        private Application mApp = Globals.Application;
        private string mAddress = string.Empty;
        private string mAddressWithSheetName = string.Empty;
        private string mWorkbookFullName;
        private string mWorkbookName;
        private string mWorksheetName;
        private bool mWorkbookOpenedProgrammatically;

        public OfflineRangeOld() // Parameterless constructor required for serialization.
        {
        }
        
        public OfflineRangeOld(Range range)
        {
            Range = range;
        }

        public ConditionsCollection Conditions { get; set; }

        public LookUpSteps LookUpSteps { get; set; }

        [XmlIgnore]
        public Range Range
        {
            get
            {
                ApplyConditions();
                
                Range range;
                if (LookUpSteps != null)
                    range = LookUpSteps.ResolveInWorksheet(Worksheet); // Note: This will open the source workbook if not currently open.
                else
                    range = GetRangeFromAddress();

                return range; ;
            }

            set
            {
                Workbook = value.Worksheet.Parent;
                Worksheet = value.Worksheet;
                Address = value.Address;
            }
        }

        void ApplyConditions()
        {
            if (Conditions != null)
                Conditions.ApplyAll();
        }

        Range GetRangeFromAddress()
        {
            // Try getting the range from it's parent worksheet. This will
            // open the range's parent workbook if it is currently closed.
            try { return Worksheet.Range[Address]; }
            catch (COMException) { throw new InvalidOperationException("Could not resolve range from literal reference."); }
        }

        public string Address // To be serialized. Must be public.
        {
            get { return mAddress; }
            set
            {
                mAddress = value;
                OnPropertyChanged("Address");
            }
        }

        public string WorksheetName  // To be serialized. Must be public.
        {
            get { return mWorksheetName; }
            set
            {
                mWorksheetName = value;
                OnPropertyChanged("WorksheetName");
            }
        }

        // Needed to get a reference to a workbook object that is already open in the current app.
        public string WorkbookName // To be serialized. Must be public.
        {
            get { return mWorkbookName; }
            set
            {
                mWorkbookName = value;
                OnPropertyChanged("WorkbookName");
            }
        }

        // Needed to get a reference to a workbook object that is currently not open.
        public string WorkbookFullName // To be serialized. Must be public.
        {
            get { return mWorkbookFullName; }
            set
            {
                mWorkbookFullName = value;
                OnPropertyChanged("WorkbookFullName");
            }
        }

        [XmlIgnore]
        public Workbook Workbook
        {
            get { return mApp.GetWorkbookFromNames(WorkbookName, WorkbookFullName, out mWorkbookOpenedProgrammatically); }
            set
            {
                //mWorkbookFullName = value.FullName;
                //mWorkbookName = value.Name;
                WorkbookFullName = value.FullName;
                WorkbookName = value.Name;
            }
        }

        [XmlIgnore]
        public Worksheet Worksheet
        {
            get { return Workbook.GetWorksheetFromName(WorksheetName); }
            set { WorksheetName = value.Name; }
        }

        public bool WorkbookOpenedProgrammatically { get { return mWorkbookOpenedProgrammatically; } }
    }
}
